#ifndef OBJECT_H
#define OBJECT_H

#include "HuntEngineSystem.h"
#include "ObjectSystemHeader.h"
#include "Rtti.h"

typedef Object* (*FactoryFunction)(Stream&);

class Object
{
// Constructor
	Object();

// Run-time type information.
public:
	virtual const Rtti& GetType () const;
	bool IsExactly ( const Rtti& rType ) const;
	bool IsDerived ( const Rtti& rType ) const;
	bool IsExactlyTypeOf ( const Object* pObj ) const;
	bool IsDerivedTypeOf ( const Object* pObj ) const;
	static const Rtti TYPE;
		
// Name Information
public:
	void SetName ( const string& rName );
	const string& GetName() const;
	virtual Object* GetObjectByName ( const string& rName );
	//virtual void GetAllObjectsByName ( const string& rName,
	//	TArray<Object*>& rObjects );
private:
	string m_Name;

// Unique Identification
public:
	unsigned int GetID () const;
	static unsigned int GetNextID ();
	virtual Object* GetObjectByID ( unsigned int uiID );
private:
	unsigned int m_uiID;
	static unsigned int ms_uiNextID;

// Sharing and Smart Pointers
public:
	void IncrementReferences ();
	void DecrementReferences ();
	int GetReferences () const;
	/*static THashTable<unsigned int, Object*> InUse;*/
	static void PrintInUse ( const char* acFilename, 
		const char* acMessage );
private:
	int m_iReferences;

// Streaming
public:
	enum { FACTORY_MAP_SIZE = 256 };
	//static THashTable<String, FactoryFunction>* ms_pFactory;
	static bool RegisterFactory ();
	static void InitializeFactory ();
	static void TerminateFactory ();
	static Object* Factory ( Stream& rStream );
	//virtual void Load ( Stream& rStream, Stream::Link* pLink );
	//virtual void Link ( Stream& rStream, Stream::Link* pLink );
	virtual bool Register ( Stream& rStream ) const;
	virtual void Save ( Stream& rStream ) const;
	virtual int GetMemoryUsed () const;
	virtual int GetDiskUsed () const;
};

#endif